home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
asm_n_z.zip
/
STATLINE.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-04-17
|
13KB
|
349 lines
;-----------------------------------------------------------------------;
; STATLINE, by John Socha, Copyright 1986 Ziff-Davis Publishing Co. ;
; ;
; Here are the two interrupt vectors that we take over. The first ;
; interrupt, INT 9, is the hardware interrupt for the keyboard, and ;
; it's called every time you push or release a key. ;
; ;
; The other interrupt, INT 10h, points to the ROM BIOS routines that ;
; handle all of the screen I/O. We intercept it so that we can watch ;
; for commands to change the display mode. Since STATLINE only works ;
; in 80x25 text modes, STATLINE turns itself off as long as the screen ;
; is in a different mode. ;
;-----------------------------------------------------------------------;
VECTORS SEGMENT AT 0h
ORG 9h*4
KEYBOARD_INT_VECTOR LABEL DWORD ;Keyboard interrupt
ORG 10h*4
VIDEO_IO_VECTOR LABEL DWORD ;ROM BIOS Video I/O function calls
VECTORS ENDS
;-----------------------------------------------------------------------;
; STATLINE uses the following flags from the ROM BIOS's data area to ;
; control the screen. ;
;-----------------------------------------------------------------------;
ROM_BIOS_DATA SEGMENT AT 40h
ORG 10h
EQUIP_FLAG DB ? ;Equipment installed
ORG 17h
KBD_FLAG DB ? ;Used to determine display type
ORG 4Eh
CRT_START DW ? ;Starting address in buffer
ORG 63h
ADDR_6845 DW ? ;3x8 register, where x is B or D
ROM_BIOS_DATA ENDS
;-----------------------------------------------------------------------;
; This section of the ROM in a COMPAQ contains the 6 bytes 'COMPAQ' ;
; which we can use to identify a COMPAQ computer. COMPAQ computers ;
; have a display adapter that uses the monochrome display, but with ;
; registers and memory the same as a color graphics adapter. ;
;-----------------------------------------------------------------------;
COMPAQ_CO EQU 4F43h ;ASCII code of 'CO'
COMPAQ_SEG SEGMENT AT 0F000h
ORG 0FFEAh
COMPAQ_ID DW ? ;We should find 'CO' (4F43h) here
COMPAQ_SEG ENDS
;-----------------------------------------------------------------------;
; Here is the STATLINE's entry point. It jumps to the initialization ;
; routine which is at the very end so that we can throw it out of ;
; memory after we've used it. ;
;-----------------------------------------------------------------------;
CODE_SEG SEGMENT
ASSUME CS:CODE_SEG, DS:CODE_SEG
ORG 100h ;Reserve for DOS Program Segment Prefix
BEGIN: JMP INIT_VECTORS
AUTHOR_STRING DB "Installed Statline, by John Socha"
DB 0Dh, 0Ah, '$'
OLD_KBD_FLAG DB 0 ;Most recent upper nibble of status
VIDEO_MODE DB ? ;Current video mode
STATUS_LINE_ENABLED DB 1 ;0 when we're in graphics modes
;-----------------------------------------------------------------------;
; The following table contains the character/attribute pairs for the ;
; states of the Scroll Lock, Num Lock, and Caps Lock keys. ;
; ;
; The first word contains the address for the character, and the second ;
; word contains the character/attribute pair. ;
;-----------------------------------------------------------------------;
ENTRY STRUC
OFFSET_FROM_TOP DW ? ;Offset from start of display memory
ATTRIBUTE_CHARACTER DB ? ;Attribute and character code
ENTRY ENDS
FLAG_CHARACTER_TABLE LABEL WORD
ENTRY <4084,' '> ;Scroll Lock, ' '
ENTRY <4084,12h> ;Scroll Lock, double-ended arrow
ENTRY <4080,' '> ;Num Lock, ' '
ENTRY <4080,23h> ;Num lock, '#'
ENTRY <4076,' '> ;Caps Lock, ' '
ENTRY <4076,18h> ;Caps Lock, up arrow
ROM_KEYBOARD_INT DD ?
ROM_VIDEO_IO_INT DD ?
;-----------------------------------------------------------------------;
; This procedure sends control off to the ROM BIOS routine, then checks ;
; the shift-lock flags on return and writes the new flag characters to ;
; the screen. ;
;-----------------------------------------------------------------------;
INTERCEPT_KEYBOARD_INT PROC FAR
ASSUME CS:CODE_SEG, DS:NOTHING
PUSHF ;Simulate INT with PUSHF and CALL
CALL ROM_KEYBOARD_INT ;Let ROM do the work
CMP STATUS_LINE_ENABLED,1 ;See if Status line enabled.
JNE NO_STATUS_LINE ;Not enabled.
CALL CHECK_STATUS_FLAGS ;Check flags and update status line
NO_STATUS_LINE:
IRET
INTERCEPT_KEYBOARD_INT ENDP
;-----------------------------------------------------------------------;
; This procedure checks the current setting of KBD_FLAGS against the ;
; last setting, and if the flags have changed, it updates the status ;
; line display. Check_status_flags also updates Old_kbd_flag. ;
;-----------------------------------------------------------------------;
CHECK_STATUS_FLAGS PROC NEAR
PUSH AX ;Save all the registers we use
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
ASSUME CS:CODE_SEG, DS:ROM_BIOS_DATA
MOV AX,ROM_BIOS_DATA ;Set DS so it points to BIOS data area
MOV DS,AX
MOV DX,ADDR_6845 ;Get the base address for the 6845
MOV AX,0B800h ;Segment address of graphics adapter
CMP DX,3D0h ;Is this the color graphics adapter?
JAE IS_COLOR_BOARD ;It's a color board, so don't change AX
MOV AX,0B000h ;Segment address for monochrome adapter
IS_COLOR_BOARD:
MOV ES,AX ;Use extra segment for display memory
ADD DX,03DAh-03D4h ;Point to status register
MOV BL,KBD_FLAG ;Get flag information
MOV CL,4 ;Put shift lock flags into lower nibble
SHR BL,CL
ASSUME CS:CODE_SEG, DS:CODE_SEG
MOV AX,CS ;Set DS to the local data (in CS)
MOV DS,AX
CMP BL,OLD_KBD_FLAG ;Have any of the status flags changed?
JE FLAGS_HAVENT_CHANGED ;No, then do nothing
MOV OLD_KBD_FLAG,BL ;Flags have changed, update status line
MOV SI,Offset FLAG_CHARACTER_TABLE
MOV CX,3 ;Repeat for three shift lock keys
SHIFT_LOCK_LOOP:
PUSH SI
SHR BL,1 ;Get next flag in carry
JNC READ_OFFSET ;Flag was 0, SI Ok
ADD SI,3 ;Skip over information
READ_OFFSET:
MOV DI,[SI] ;Get Offset
MOV AL,[SI+2] ;Get character for this flag
PUSH CX ;Save the CX register
MOV CL,AL ;Save the character in CL
WAIT_FOR_NON_RETRACE:
IN AL,DX ;Read status
TEST AL,8 ;In vertical retrace?
JNZ WAIT_FOR_NON_RETRACE ;Wait for vertical retrace to finish
WAIT_FOR_RETRACE:
IN AL,DX ;Read status
TEST AL,8 ;In vertical retrace?
JZ WAIT_FOR_RETRACE ;No, then wait for vertical retrace
MOV AL,CL ;Get the character we want to write
STOSB ;Write character to the screen
POP CX ;Recover the old value of CX
POP SI
ADD SI,6 ;Skip to next pair of entries
LOOP SHIFT_LOCK_LOOP
FLAGS_HAVENT_CHANGED:
POP ES
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
RET
CHECK_STATUS_FLAGS ENDP
;-----------------------------------------------------------------------;
; This procedure reprograms the 6845 whenever a program switches modes ;
; into an 80x25 text mode. ;
;-----------------------------------------------------------------------;
INTERCEPT_VIDEO_IO PROC FAR
ASSUME CS:CODE_SEG, DS:NOTHING
OR AH,AH ;Check if called for SET MODE
JZ SET_MODE ;It's a SET MODE call
JMP ROM_VIDEO_IO_INT ;Not a SET MODE, call ROM BIOS
SET_MODE:
MOV VIDEO_MODE,AL ;Save new video mode
MOV STATUS_LINE_ENABLED,AH ;Disable STATLINE during mode change
PUSHF ;Simulate INT with PUSHF, CALL
CALL ROM_VIDEO_IO_INT ;Let ROM BIOS change video mode
CALL REPROGRAM_6845 ;Create 26th line again
MOV OLD_KBD_FLAG,0 ;Flags will be clear in new mode
CALL CHECK_STATUS_FLAGS ;Make sure we show current flags
IRET
INTERCEPT_VIDEO_IO ENDP
;-----------------------------------------------------------------------;
; The following tables describe how to reprogram the 6845 registers. ;
; Each pair describes how to change one register. The first number is ;
; the register that we want to reprogram, while the second number is ;
; the new value for that register. Reprogram_6845 stops when it sees ;
; a 0 for the register number. ;
;-----------------------------------------------------------------------;
MONOCHROME_TABLE LABEL BYTE
DB 4,26 ;Vertical total, 26 lin